package com.smartian.v2.impl;

import android.text.TextUtils;


import com.smartian.v2.AbstractTextParser;
import com.smartian.v2.OpLog;
import com.smartian.v2.TextPattern;
import com.smartian.v2.filters.TextParserInterceptorManager;
import com.smartian.v2.model.DateTimeNode;
import com.smartian.v2.model.ScheduleTaskBean;
import com.smartian.v2.utils.DateTimeHelper;
import com.smartian.v2.utils.FestivalFilter;

import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collections;
import java.util.List;
import java.util.regex.Matcher;

/**
 * Created by tianweitong on 2020/3/13.
 */

public class DefaultTextParser extends AbstractTextParser {

    private volatile boolean mHasParsed = false;
    private final List<DateTimeNode> mDateTimeNodeList  = new ArrayList<>();

    public DefaultTextParser(String sourceText, String repeatText, int repeatTextIndex) {
        super(sourceText, repeatText, repeatTextIndex);
    }

    //年月日，前天，后天，大后天，明天，明晚，明早，今晚，今天，中午，上午，下午，晚上，早上，凌晨，午后，午时N刻，周N
    //N点M刻，M天后，M分钟后，M秒后,M周后,月底，月初，月中旬
    @Override
    public ScheduleTaskBean getScheduleTaskBean() {

        startHandler();

        if(mDateTimeNodeList!=null) {
            Collections.sort(mDateTimeNodeList);
        }
        OpLog.d("TextParser",mDateTimeNodeList+"");

        DateTimeNode dateNode = DateTimeHelper.findBestDateNode(mDateTimeNodeList,DateTimeNode.TYPE_DATE);
        DateTimeNode timeNode = DateTimeHelper.findBestDateNode(mDateTimeNodeList,DateTimeNode.TYPE_TIME);

        if(dateNode==null || timeNode==null){
            return null;
        }
        if(TextUtils.isEmpty(dateNode.resultText) || TextUtils.isEmpty(timeNode.resultText)){
            return null;
        }

        List<DateTimeNode> dateTimeNodes  = new ArrayList<>();

        dateTimeNodes.add(dateNode);
        dateTimeNodes.add(timeNode);

        String date = dateNode.resultText;
        String time = timeNode.resultText;


        String dateTime = DateTimeHelper.getFullDateTime(date,time);

        ScheduleTaskBean scheduleTaskBean = new ScheduleTaskBean();
        scheduleTaskBean.setFraquent(1);
        scheduleTaskBean.setRepeatType(TextPattern.REPEAT_NONE);
        scheduleTaskBean.setDateTime(dateTime);
        scheduleTaskBean.setDateTimeFormat(getDateTimeFormat());
        scheduleTaskBean.setSourceText(getSourceText());
        scheduleTaskBean.setDateTimeNodes(dateTimeNodes);

        return scheduleTaskBean;
    }


    private void startHandler() {
        if(!mHasParsed) {
            List<DateTimeNode> dateTimeNodes = startParse();
            if (dateTimeNodes != null) {
                mDateTimeNodeList.clear();
                dateTimeNodes = TextParserInterceptorManager.dispatchIntercept(this,TextPattern.REPEAT_NONE,dateTimeNodes);
                mDateTimeNodeList.addAll(dateTimeNodes);
            }
            mHasParsed = true;
        }
    }

    private List<DateTimeNode> startParse() {
        List<DateTimeNode> dtns = new ArrayList<>();

        String sourceText = getSourceText();

        if(TextUtils.isEmpty(sourceText)) return dtns;

        List<DateTimeNode> dateNodes = getParseDate();
        List<DateTimeNode> festivalDateNodes = FestivalFilter.getInstance().getFilterDateNodes(sourceText);
        if(festivalDateNodes!=null){
            dateNodes.addAll(festivalDateNodes);
            Collections.sort(dateNodes);
        }

        List<DateTimeNode> timeNodes = getParseTime();

        if(dateNodes.size()==0 && timeNodes.size()>0){
            DateTimeNode InferTimeNode = tryInferDate(timeNodes);
            if(InferTimeNode!=null){
                dateNodes.add(InferTimeNode);
            }
        }

        if(timeNodes.size()==0 && dateNodes.size()>0){

            DateTimeNode timeNode = new DateTimeNode();
            timeNode.text = "";
            timeNode.index = 0;
            timeNode.resultText = DateTimeHelper.getCurrentTime();
            timeNode.locatorText = "";
            timeNode.type = DateTimeNode.TYPE_TIME;
            timeNodes.add(timeNode);

        }

        if(dateNodes!=null){
            dtns.addAll(dateNodes);
        }
        if(timeNodes!=null) {
            dtns.addAll(timeNodes);
        }

        return dtns;

    }



    private DateTimeNode tryInferDate( List<DateTimeNode> timeNodes) {


        if(timeNodes.size()==0) {

            return null;
        }

        Calendar calendar = Calendar.getInstance();

        int HOUR = calendar.get(Calendar.HOUR_OF_DAY);
        int MINUTE = calendar.get(Calendar.MINUTE);

        String date = null;

        DateTimeNode dateTimeNode = timeNodes.get(timeNodes.size() - 1);
        String resultText = dateTimeNode.resultText;
        Matcher matcher = TextPattern.REG_EXP_TIME.matcher(resultText);
        if (matcher.find()) {
            String hour = DateTimeHelper.readPrevNumberAtFlag(resultText, TextPattern.TIME_SEPATOR);
            String min = DateTimeHelper.readNextNumberAtFlag(resultText, TextPattern.TIME_SEPATOR);

            long stamp = DateTimeHelper.getIntegerValue(hour) * 60 + DateTimeHelper.getIntegerValue(min);
            if ((stamp - (HOUR * 60 + MINUTE)) < 0) {
                calendar.add(Calendar.DAY_OF_MONTH, 1);
                date = TextPattern.sDateFormat.format(calendar.getTime());
            } else {
                date = DateTimeHelper.getToday();
            }

        } else {
            date = DateTimeHelper.getToday();
        }

        if(TextUtils.isEmpty(date)){
            return null;
        }

        DateTimeNode dateNode = new DateTimeNode();
        dateNode.text = "";
        dateNode.index = 0;
        dateNode.resultText = date;
        dateNode.locatorText = "";
        dateNode.type = DateTimeNode.TYPE_DATE;

        return dateNode;
    }


    @Override
    public boolean isValid() {
        startHandler();
        return mDateTimeNodeList.size()>0;
    }

    @Override
    public String getDateTimeFormat() {
        return "yyyy-MM-dd HH:mm";
    }
}
